package com.hoow.shakoow.shake

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.graphics.drawable.ColorDrawable
import android.hardware.Sensor
import android.hardware.SensorManager
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.SoundPool
import android.os.*
import android.view.View
import android.view.animation.Animation
import android.view.animation.Animation.AnimationListener
import android.view.animation.TranslateAnimation
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.bumptech.glide.Glide
import com.google.android.ads.nativetemplates.NativeTemplateStyle
import com.google.android.gms.ads.*
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.rewarded.RewardedAd
import com.google.android.gms.ads.rewarded.RewardedAdLoadCallback
import com.hoow.shakoow.R
import com.hoow.shakoow.ai.data.ReqAiBase
import com.hoow.shakoow.ai.data.ReqGetShakeUserInfo
import com.hoow.shakoow.ai.data.ReqLookedAdvert
import com.hoow.shakoow.ai.home.NetworkViewModel
import com.hoow.shakoow.base.BaseActivity
import com.hoow.shakoow.databinding.ActivityShakeBinding
import com.hoow.shakoow.enums.PageTagEnum
import com.hoow.shakoow.extend.*
import com.hoow.shakoow.shake.components.dialog.PurchaseTimesDialog
import java.util.concurrent.atomic.AtomicBoolean


/** 启动页 */
@SuppressLint("CustomSplashScreen")
class ShakeActivity_bc : BaseActivity() {

    // 布局binding
    private lateinit var mActivityBinding: ActivityShakeBinding

    // 弹框
    private lateinit var mPurchaseTimesDialog: PurchaseTimesDialog

    // 广告
//    private var mInterstitialAd: InterstitialAd? = null
    //    private val AD_UNIT_ID_REWARD = "ca-app-pub-3940256099942544/1033173712"

    private var rewardedAd: RewardedAd? = null
    private val isMobileAdsInitializeCalled = AtomicBoolean(false)
    private val AD_UNIT_ID_REWARD =
        "ca-app-pub-3940256099942544/5224354917"//"ca-app-pub-3940256099942544/5224354917"//"ca-app-pub-3940256099942544/5354046379"

    private var currentNativeAd: NativeAd? = null
    private val AD_UNIT_ID_NATIVE = "ca-app-pub-3940256099942544/2247696110"

    // 准备好后是否需要立即展示
    private var isNeedShowRewardAdsWhenLoadFinish = false

    // 线程句柄
    private val mStartAniHandler = Handler(Looper.getMainLooper())
    private val mEndAniHandler = Handler(Looper.getMainLooper())
    private val mShowDialogAniHandler = Handler(Looper.getMainLooper())

    // 是否在摇一摇中
    private var mIsShaking = false

    // 你可以定义任何非负整数作为请求码
    private val VIBRATION_REQUEST_CODE = 123

    private var mSensorManager: SensorManager? = null

    private var shakeDetector: ShakeDetector? = null

    private var isOpen: Boolean = false

    //手机震动
    private var mVibrator: Vibrator? = null

    //摇一摇音效
    private var mSoundPool: SoundPool? = null

    //摇一摇音效
    private var mWeiChatAudio = 0

    //api接口viewModel
    private val mNetworkViewModel by lazy {
        ViewModelProvider(this)[NetworkViewModel::class.java]
    }

    override fun onBindingViewModel(): List<ViewModel> {
        val list = mutableListOf<ViewModel>()
        list.add(mNetworkViewModel)
        return list
    }

    override fun onBindingViewTag(): String {
        return PageTagEnum.shake.name.uppercase()
    }

    override fun onBindingContentView(): View {
        mActivityBinding = ActivityShakeBinding.inflate(layoutInflater)
        return mActivityBinding.root
    }

    @SuppressLint("SetTextI18n", "SourceLockedOrientationActivity", "WrongConstant")
    override fun onContentViewBinded() {
        try {
            // 如果已打开，就退出
            if (intent.flags and Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT != 0) {
                finish()
                return
            }
            // 设置只竖屏
            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

            // 初始化广告弹框
            mPurchaseTimesDialog = PurchaseTimesDialog()
            mPurchaseTimesDialog.setOnActionClickListener { action ->
                if (action == PurchaseTimesDialog.ACTION_WATCH_ADS) {
                    println("===> load reward ad")
                    // 看广告
                    showRewardAds()

                } else if (action == PurchaseTimesDialog.ACTION_PURCHASE) {
                    // 购买
                    startToUserRechargePage()

                } else if (action == PurchaseTimesDialog.ACTION_LOAD_ADS) {
                    println("===> load native ad")
                    // load native ad
                    refreshNativeAd()
                }
            }

            // 初始化SoundPool
            initSoundPool()

            // 获取Sensor震动服务
            mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

            // 获取Vibrator震动服务
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                val vibratorManager =
                    getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
                mVibrator = vibratorManager.defaultVibrator
            } else {
                mVibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
            }

            shakeDetector = ShakeDetector()
            shakeDetector?.setOnShakeListener {
                if (mIsShaking) return@setOnShakeListener
                if (isOpen) return@setOnShakeListener
                if (mPurchaseTimesDialog.isVisible) return@setOnShakeListener

                // 更新状态
                mIsShaking = true

                // 在这里执行摇一摇后的操作
                //vibrate()

                if (mNetworkViewModel.mShakeId.isNotBlank()) {
                    // 获取摇到的用户信息
                    val reqGetShakeUserInfo =
                        ReqGetShakeUserInfo(shakeId = mNetworkViewModel.mShakeId)
                    reqGetShakeUserInfo.showLoading = false
                    mNetworkViewModel.getShakeUserInfo(reqGetShakeUserInfo)
                } else {
                    // 调用摇一摇接口
                    mNetworkViewModel.startShake(ReqAiBase(showLoading = false))
                }

                // 播放声音
                // mSoundPool?.play(mWeiChatAudio, 1.0f, 1.0f, 1, 0, 1.0f)

                // 开始联合动画
                startShakeUnionAnimation()
            }

            // 检查振动权限
            if (checkVibrationPermission()) {
                // 如果有振动权限，执行相应的操作
                performShakeAction()
            } else {
                // 如果没有振动权限，请求权限
                requestVibrationPermission()
            }

            // 开始摇一摇回调
            mNetworkViewModel.onStartShakeLiveData.observe(this) {
                if (it.isSuccess) {
                    it.getOrNull()?.let { result ->
                        // 保存当前shake id
                        mNetworkViewModel.mShakeId = result.shakeId ?: ""

                        // 判断是否可摇
                        val canShake = result.canShake ?: ""
                        if (canShake.equals("YES", true)) {
                            // 获取摇到的用户信息
                            val reqGetShakeUserInfo =
                                ReqGetShakeUserInfo(shakeId = mNetworkViewModel.mShakeId)
                            reqGetShakeUserInfo.showLoading = false
                            mNetworkViewModel.getShakeUserInfo(reqGetShakeUserInfo)
                        } else {
                            // 展示关闭动画
                            endShakeUnionAnimation()

                            // 弹广告
                            mShowDialogAniHandler.removeCallbacksAndMessages(null)
                            mShowDialogAniHandler.postDelayed({
                                if (!mPurchaseTimesDialog.isVisible) {
                                    mPurchaseTimesDialog.show(
                                        supportFragmentManager,
                                        PurchaseTimesDialog::class.java.simpleName
                                    )
                                }
                            }, 1300)
                        }
                    }
                    if (it.getOrNull() == null) {
                        // 展示关闭动画
                        endShakeUnionAnimation()
                    }
                } else {
                    // 展示关闭动画
                    endShakeUnionAnimation()
                }
            }

            // 摇一摇返回的用户回调
            mNetworkViewModel.onGetShakeUserInfoLiveData.observe(this) {
                if (it.isSuccess) {
                    it.getOrNull()?.let { result ->
                        mNetworkViewModel.mShakeId = ""
                        mNetworkViewModel.mShakeResultUserInfo = result
                        ShakeUserManager.mCurShakeUserInfo = result
                        ShakeUserManager.mCurShakeId = result.shakeId
                        ShakeUserManager.mCurUserId = result.userId

                        // 设置图像
                        result.headImg?.let { url ->
                            if (url.isValidLink()) {
                                Glide.with(mActivityBinding.imageShakeResult)
                                    .load(url)
                                    .into(mActivityBinding.imageShakeResult)
                            }
                        }

                        // 设置签名
                        mActivityBinding.textShakeResultNickName.text = result.name

                        // 设置性别
                        if (result.sex.equals("0", true)) {
                            mActivityBinding.imageShakeResultGender.setImageResource(R.drawable.icon_female)
                        } else {
                            mActivityBinding.imageShakeResultGender.setImageResource(R.drawable.icon_male)
                        }
                    }
                }

                // 展示结果动画
                endShakeUnionAnimation()
            }

            // 记录看完广告
            mNetworkViewModel.onSaveLookedAdvertLiveData.observe(this) {
                println("===> 记录看完广告")
            }

            // 点击我的
            mActivityBinding.imageMe.setOnClickListener {
                if (mIsShaking) return@setOnClickListener
                if (isOpen) return@setOnClickListener
                if (mPurchaseTimesDialog.isVisible) return@setOnClickListener

                //跳转我的页面
                startToMyDetailPage()
            }

            // 点击摇到的
            mActivityBinding.vShakeResultBg.setOnClickListener {
                if (mIsShaking) return@setOnClickListener
                if (isOpen) return@setOnClickListener
                if (mPurchaseTimesDialog.isVisible) return@setOnClickListener

                val params = HashMap<String, String>()
                params["userId"] = ShakeUserManager.mCurUserId ?: ""
                params["shakeId"] = ShakeUserManager.mCurShakeId ?: ""
                startToUserDetailPage(params)
            }

            // 测试点击
            mActivityBinding.llShakeBottomImageBg.setOnClickListener {
                // 显示动画
                startShakeUserResultAnimation()
            }

            // 测试点击
            mActivityBinding.llShakeTopImageBg.setOnClickListener {
                if (mIsShaking) return@setOnClickListener
                if (isOpen) return@setOnClickListener
                if (mPurchaseTimesDialog.isVisible) return@setOnClickListener

                // 更新状态
                mIsShaking = true

                // 开始摇一摇
                if (mNetworkViewModel.mShakeId.isNotBlank()) {
                    // 获取摇到的用户信息
                    val reqGetShakeUserInfo =
                        ReqGetShakeUserInfo(shakeId = mNetworkViewModel.mShakeId)
                    reqGetShakeUserInfo.showLoading = false
                    mNetworkViewModel.getShakeUserInfo(reqGetShakeUserInfo)
                } else {
                    // 调用摇一摇接口
                    mNetworkViewModel.startShake(ReqAiBase(showLoading = false))
                }

                // 播放声音
                // mSoundPool?.play(mWeiChatAudio, 1.0f, 1.0f, 1, 0, 1.0f)

                // 开始联合动画
                startShakeUnionAnimation()
            }

            // 加载中动画
            mActivityBinding.aviShakeLoading.show()

            // 初始化广告sdk
            initializeMobileAdsSdk()

        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onResume() {
        super.onResume()

        //获取 SensorManager 负责管理传感器
        mSensorManager?.let { sensorManager ->
            val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
            sensorManager.registerListener(
                shakeDetector,
                accelerometer,
                SensorManager.SENSOR_DELAY_NORMAL
            )
        }

        // 设置摇一摇音量
        val audioManager: AudioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
        val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume / 2, 0)
    }

    override fun onPause() {
        mEndAniHandler.removeCallbacksAndMessages(null)
        mStartAniHandler.removeCallbacksAndMessages(null)
        mShowDialogAniHandler.removeCallbacksAndMessages(null)

        // 务必要在pause中注销 mSensorManager
        // 否则会造成界面退出后摇一摇依旧生效的bug
        if (mSensorManager != null) {
            mSensorManager!!.unregisterListener(shakeDetector)
        }
        super.onPause()
    }

    override fun onDestroy() {
        mEndAniHandler.removeCallbacksAndMessages(null)
        mStartAniHandler.removeCallbacksAndMessages(null)
        mShowDialogAniHandler.removeCallbacksAndMessages(null)
//        currentNativeAd?.destroy()
        super.onDestroy()
    }

    private fun initializeMobileAdsSdk() {
        if (isMobileAdsInitializeCalled.getAndSet(true)) {
            return
        }

        val testDeviceIds = listOf("88786D0FBEF9BEFFF6AB52089CD8BA89")
        val configuration = RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build()
        MobileAds.setRequestConfiguration(configuration)

        // Initialize the Mobile Ads SDK.
        MobileAds.initialize(this) {
            println("===> MobileAds Ad init completed")
            // Load reward ad.
            loadRewardedAd()
        }
    }

    ///////////// Reward Ads ////////////////
    private fun showRewardAds() {
        if (rewardedAd != null) {
            rewardedAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
                override fun onAdClicked() {
                    // Called when a click is recorded for an ad.
                    println("===> rewards Ad was clicked.")
                }

                override fun onAdDismissedFullScreenContent() {
                    // Called when ad is dismissed.
                    println("===> rewards Ad dismissed fullscreen content.")
                    rewardedAd = null

                    // 重新加载
                    loadRewardedAd()
                }

                override fun onAdFailedToShowFullScreenContent(adError: AdError) {
                    // Called when ad fails to show.
                    println("===> rewards Ad failed to show fullscreen content.")
                    rewardedAd = null
                }

                override fun onAdImpression() {
                    // Called when an impression is recorded for an ad.
                    println("===> rewards Ad recorded an impression.")

                }

                override fun onAdShowedFullScreenContent() {
                    // Called when ad is shown.
                    println("===> rewards Ad showed fullscreen content.")
                }
            }

            rewardedAd?.show(this) { rewardItem ->
                // Handle the reward.
                val rewardAmount = rewardItem.amount
                val rewardType = rewardItem.type
                println("===> rewards Ad User earned the reward. amount:$rewardAmount type:$rewardType")

                // 记录看完广告
                val reqLookedAdvert = ReqLookedAdvert(adId = rewardType)
                reqLookedAdvert.showLoading = false
                mNetworkViewModel.saveLookedAdvert(reqLookedAdvert)
            }
        } else {
            isNeedShowRewardAdsWhenLoadFinish = true
            println("===> The rewarded Ad wasn't ready yet.")
            loadRewardedAd()
        }
    }

    private fun loadRewardedAd() {
        if (rewardedAd == null) {
            val adRequest = AdRequest.Builder().build()

            RewardedAd.load(
                this,
                AD_UNIT_ID_REWARD,
                adRequest,
                object : RewardedAdLoadCallback() {
                    override fun onAdFailedToLoad(adError: LoadAdError) {
                        println("===> rewards ${adError.message}")
                        rewardedAd = null
                    }

                    override fun onAdLoaded(ad: RewardedAd) {
                        println("===> rewards Ad was loaded.")
                        rewardedAd = ad

                        if (isNeedShowRewardAdsWhenLoadFinish) {
                            isNeedShowRewardAdsWhenLoadFinish = false
                            showRewardAds()
                        }
                    }
                }
            )
        }
    }

    ///////////// Native Ads ////////////////
    private fun refreshNativeAd() {
        val adLoader: AdLoader = AdLoader.Builder(this, AD_UNIT_ID_NATIVE)
            .forNativeAd { nativeAd ->
                println("===> forNativeAd nativeAd")
                val colorDrawable = ColorDrawable(
                    ContextCompat.getColor(
                        this@ShakeActivity_bc,
                        R.color.background_form_input
                    )
                )
                val styles =
                    NativeTemplateStyle.Builder().withMainBackgroundColor(colorDrawable).build()
                val template =
                    mPurchaseTimesDialog.mViewBinding.myTemplate// findViewById<TemplateView>(R.id.my_template)
                template.setStyles(styles)
                template.setNativeAd(nativeAd)
            }
            .withAdListener(object : AdListener() {
                override fun onAdClicked() {
                    super.onAdClicked()
                    println("===> onAdClicked")
                }

                override fun onAdClosed() {
                    super.onAdClosed()
                    println("===> onAdClosed")
                }

                override fun onAdFailedToLoad(p0: LoadAdError) {
                    super.onAdFailedToLoad(p0)
                    println("===> onAdFailedToLoad")
                }

                override fun onAdImpression() {
                    super.onAdImpression()
                    println("===> onAdImpression")
                }

                override fun onAdLoaded() {
                    super.onAdLoaded()
                    println("===> onAdLoaded")
                }

                override fun onAdOpened() {
                    super.onAdOpened()
                    println("===> onAdOpened")
                }

                override fun onAdSwipeGestureClicked() {
                    super.onAdSwipeGestureClicked()
                    println("===> onAdSwipeGestureClicked")
                }
            })
            .build()

        adLoader.loadAd(AdRequest.Builder().build())
    }

    private fun vibrate() {
        // 震动手机
        if (mVibrator != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            mVibrator!!.vibrate(
                VibrationEffect.createOneShot(
                    500,
                    VibrationEffect.DEFAULT_AMPLITUDE
                )
            )
        } else if (mVibrator != null) {
            @Suppress("DEPRECATION")
            mVibrator!!.vibrate(500)
        }
    }

    private fun checkVibrationPermission(): Boolean {
        return ContextCompat.checkSelfPermission(
            this,
            android.Manifest.permission.VIBRATE
        ) == PackageManager.PERMISSION_GRANTED
    }

    private fun requestVibrationPermission() {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(android.Manifest.permission.VIBRATE),
            VIBRATION_REQUEST_CODE
        )
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            VIBRATION_REQUEST_CODE -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // 用户授予了振动权限
                    performShakeAction()
                } else {
                    // 用户拒绝了振动权限
                    // 在这里可以提供一些用户提示或处理
                }
            }
        }
    }

    private fun performShakeAction() {
        // 在这里执行摇一摇后的操作
        println("在这里执行摇一摇后的操作")
    }

    /** 创建 SoundPool */
    private fun initSoundPool() {
        try {
            val audioAttributes = AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build()

            mSoundPool = SoundPool.Builder()
                .setMaxStreams(1)
                .setAudioAttributes(audioAttributes)
                .build()

            mWeiChatAudio = mSoundPool?.load(this, R.raw.weichat_audio, 1)!!
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 结束摇一摇联合动画
     */
    private fun endShakeUnionAnimation() {
        // 展示结果动画
        mEndAniHandler.removeCallbacksAndMessages(null)
        mEndAniHandler.postDelayed({
            // 展开动画
            startShakeUserResultAnimation()
            // 展开动画
            startAnimation(isOpen)
        }, 1000)
    }

    /**
     * 开始摇一摇联合动画
     */
    private fun startShakeUnionAnimation() {
        // 关闭动画
        startShakeUserResultCloseAnimation()

        // 展开动画
        startAnimation(isOpen)
    }

    /**
     * 关闭摇到用户的动画
     */
    private fun startShakeUserResultCloseAnimation() {
        if (mActivityBinding.rlShakeResultBg.visibility == View.VISIBLE) {
            // 计算Y轴坐标
            val pHeight = mActivityBinding.rlShakeRootBg.height
            val vHeight = mActivityBinding.rlShakeResultBg.height
            val vTop = mActivityBinding.rlShakeResultBg.top
            val vEdge = pHeight - vTop
            val vDiv = (vEdge * 1F / vHeight) + 0.2F

//            println("pHeight: $pHeight  vHeight:$vHeight  vTop:$vTop  vBottom:$vBottom")
//            println("vCurTop: $vCurTop  vCurBottom:$vCurBottom  vEdge:$vEdge  vDiv:$vDiv")

            val type = Animation.RELATIVE_TO_SELF

            val topAnim = TranslateAnimation(
                type, 0f, type, 0f, type, 1.2F, type, vDiv
            )
            topAnim.duration = 200
            topAnim.fillAfter = true

            topAnim.setAnimationListener(object : AnimationListener {
                override fun onAnimationStart(animation: Animation?) {
                }

                override fun onAnimationEnd(animation: Animation?) {
                    mActivityBinding.rlShakeResultBg.visibility = View.GONE
                }

                override fun onAnimationRepeat(animation: Animation?) {
                }
            })

            mActivityBinding.rlShakeResultBg.startAnimation(topAnim)
        }
    }

    /**
     * 显示摇到用户的动画
     */
    private fun startShakeUserResultAnimation() {
        if (mNetworkViewModel.mShakeResultUserInfo != null) {
            mActivityBinding.rlShakeResultBg.visibility = View.VISIBLE
            mActivityBinding.vShakeResultBg.visibility = View.VISIBLE
            val type = Animation.RELATIVE_TO_SELF

            val topAnim = TranslateAnimation(
                type, 0f, type, 0f, type, 0F, type, 1.2F
            )
            topAnim.duration = 200
            topAnim.fillAfter = true
            mActivityBinding.rlShakeResultBg.startAnimation(topAnim)
        } else {
            mActivityBinding.vShakeResultBg.visibility = View.GONE
        }
    }

    /**
     * 开启 摇一摇动画
     *
     * @param isBack 是否是返回初识状态
     */
    private fun startAnimation(isBack: Boolean) {
        // 动画坐标移动的位置的类型是相对自己的
        val type = Animation.RELATIVE_TO_SELF
        val topFromY: Float
        val topToY: Float
        val bottomFromY: Float
        val bottomToY: Float
        if (isBack) {
            topFromY = -1.2f
            topToY = 0f
            bottomFromY = 1.2f
            bottomToY = 0f
        } else {
            topFromY = 0f
            topToY = -1.2f
            bottomFromY = 0f
            bottomToY = 1.2f
        }

        // 顶部动画效果
        val topAnim = TranslateAnimation(
            type, 0f, type, 0f, type, topFromY, type, topToY
        )
        topAnim.duration = 200

        // 动画终止时停留在最后一帧
        topAnim.fillAfter = true

        // 底部动画效果
        val bottomAnim = TranslateAnimation(
            type, 0f, type, 0f, type, bottomFromY, type, bottomToY
        )
        bottomAnim.duration = 200

        // 动画终止时停留在最后一帧
        bottomAnim.fillAfter = true

        // 动画结束
        bottomAnim.setAnimationListener(object : AnimationListener {
            override fun onAnimationStart(animation: Animation) {}
            override fun onAnimationRepeat(animation: Animation) {}
            override fun onAnimationEnd(animation: Animation) {
                //当动画结束后 , 将中间两条线GONE掉, 不让其占位
                if (isBack) {
                    mIsShaking = false
                }
            }
        })
        //设置动画
        mActivityBinding.llShakeTopImageBg.startAnimation(topAnim)
        mActivityBinding.llShakeBottomImageBg.startAnimation(bottomAnim)

        isOpen = !isOpen
    }
}